区块链7 |
您所在的位置:网站首页 › solidity 合约转账给合约 › 区块链7 |
Solidity语言详解 1.文件结构 2.数据结构 3.错误处理
11.参数 12.控制结构 13.可见性 14.函数
1.1合约文件结构 1.1.1版权申明 1.1.2import 1.1.3合约 1.1.3.1状态变量 1.1.3.2函数 1.1.3.3结构类型 1.1.3.4事件 1.1.3.5函数修改器 1.1.4代码注释
语言类型 动态:运行时确定某个变量类型 egg:javascript 静态:声明的时候,编译的时候,指定变量类型或者至少编译时推导出类型,常见的有c,c++,java solidity静态 值类型 重点booleans integers string address 引用类型
布尔类型 取值 true/false 运算符! && || == !=
整型 int/unit 关键字unit8到unit256(以8步进) 运算符 -比较运算符 -位运算符&,|,^,~ 算术运算
常量(字面量) 有理数和整型常量 字符串常量 十六进制常量 地址常量
地址类型 address:表示一个账户地址(20字节) 成员 属性:balance余额 函数:transfer()用于转移以太币 地址常量 地址合法性检查
引用类型 数据位置 memory内存,storage永久 数组 -T[k]:元素类型为T,固定长度为k的数组 -T[]:数组类型为T,长度动态调整 -bytes string:是一种特殊的数组 -string 可转为bytes,bytes类似byte[] 数组成员:属性:length 函数:push()
结构体 struct 映射(Mappings) mapping(address=>uint) public balances;
全局变量和函数 -有关区块和交易! msg.sender(address)获取交易发送者地址 msg.value(uint)当前交易所附带的以太币,单位是位 block.coinbase(address)当前块的地址 block.difficulty(uint)当前块的难度 block.number(uint)当前区块的块号 block.timestamp(uint)当前块时间戳 now(uint)当前区块的时间戳,实际上是timestamp的别名 tx.gasprice(uint)当前交易的价格 -有关错误处理! 什么是错误处理 指在程序发生错误时的处理方式 处理方式 回退状态 assert (通常检查函数内部的错误,消耗所有提供的gas,egg:下标越界,整数/0,assert方法调用参数时false,是assert类型异常)。require(检查输入的变量或者合约的状态变量是否满足条件,通常时外部 合约的条件,不会消耗提供的gas,egg:gas不足,没有匹配到正常的函数等等) 把区块链当作分布式事务性数据库:数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的 全部数据库操作组成。[1] -有关数字及加密功能 -有关地址和合约
函数参数 -输入参数 -输出参数 函数的返回值 -命名参数 {a: 1, b: 3} -参数解构 用在函数式编程比较多
控制结构 if,else,while,do,for,break结束本次循环,continue下一步,return,?: 没有switch goto
可见性 -public 函数默认可见性,公开函数是合约接口的一部分,可以通过内部,或者消息调用。对于public类型的状态变量,会自动创建一个访问器(可以理解为get函数) -private 私有的函数和状态变量仅在 当前合约 中可以访问,在继承的合约内不可访问(不能修改,可以看到) -external 外部函数是合同接口的一部分,只能使用 消息调用 -internal 状态变量默认的可见性,函数和状态只能通过内部访问。如在 当前合约 或 继承合约 里调用 表达式 this.g(8);和 c.g(2)(这里的 c 是一个合约实例)是外部调用函数的方式,它会发起一个消息调用 public和external区别 public多了一个调用方式,如果我们有一个函数,它只接收外部调用的话,使用external而不是public,因为external消耗gas更少 方式=内部+消息调用 内部=当前合约+继承合约 消息调用=this+c.g() public为方式 private为方式->内部->当前合约 external为方式->消息调用 internal为方式->内部
函数 -构造函数 -视图函数(constant/view)(不会修改 状态变量)(不能触发事件-认为是修改状态变量)(不能创建合约) -纯函数(pure)(既不会读也不会修改 状态变量) -回退函数(无名函数,一个智能合约需要接受以太币的时候,我们就需要实现这样的回退函数,它是一个被动调用的函数) pragma solidity ^0.4.0; import "solidity_for_import.sol"; // This is a test Contract contract Test { uint a; bool boola = true; bool boolb = false; int256 c = 20; // int256==int int256 d = 30; function testadd() public constant returns (int) { if (b > c){ return b + c } else if (b == c){ return b * c } else { return b >> 2 } } function testLiterals() public constant returns (int) { return 1231321321.0 * 1.5e10; } function testStringLiterals() public constant returns (string) { return "abc"; } function testHexLiterals() public constant returns (bytes2, bytes1, bytes1) { bytes2 a = hex"abcd" return (a, a[0], a[1];) } function testbool1() returns (bool) { return boola && boolb; } function testbool2() returns (bool) { return boola || boolb; } function testbool3() returns (bool) { return !boola } function setA(unit x) public { a = x emit Set_A(X); } event Set_A(uint a); struct Position { int lat: int lng } address public owerAddr; // 修改函数的行为 函数修改器 modifier owner () { require(msg.sender == owerAddr); _; } function mine() public owner { a += 1; } } solidity_for_import.sol pragma solidity ^0.4.0; contract ForImport { } pragma solidity ^0.4.0; contract ArrayTest{ uint[] public u = [1, 2, 3]; string s = "abcdefg; function h() public returns (uint) { u.push(4); return u.length; } function f() public view returns (byte) { return bytes(s)[1]; } function new(uint len) constant public returns (uint) { uint[] memory a = new uint[] (len); bytes memory b = new bytes(len); a[6] = 8; // 错a.length = 100; // 对u.length = 100; g([unit(1), 2, 3]); return a.length; } function g(uint[3] _data) public constant { } struct Funder { address addr; uint amount; } Funder funder; function newFunder() public { funder = Funder({addr: msg.sender, amount: 10}); } mapping(address=>uint) public balances; function updateBalance(uiny newBalance) public { balances[msg.sender] = newBalance } function testApi1() public constant returns (address) { return msg.sender; } constructor() payable { } function testApi2() public payable returns (uint) { return msg.value; } function testApi3() public constant returns (address) { return block.coinbase; } function testApi4() public constant returns (uint) { return block.difficulty; } function testApi5() public constant returns (uint) { return block.number; } } pragma solidity ^0.4.0; contract Test{ function simpleIntput(uint a, uint b) public constant returns (uint sum, uint mul) { sum = a + b mul = a * b } function testSimpleInput() public constant returns (uint sum, uint mul) { //sum = simpleIntput({a: 1, b: 3}); // 等于sum = simpleIntput({b: 1, a: 3}); (sum, mul) = simpleIntput({ b : 3, a : 1}); } function f() public constant returns (uint, bool, uint) { return (7, true, 2) } function g() public { var (x, y, z) = f() (, y, z) = f() (x, ) = (1, 2); // 交换x和z的值 (x, z) = (z, x) } } pragma solidity ^0.4.0; contract Test{ uint public data; // 生成访问器,可以理解为get函数 function f(uint a) privare returns (uint b) { return a + 1; } function setData(uint a) internal { data = a; } function exSetData(uint a) external { data = a; } function testsetData() public { setData(1); this.exSetData(1); // 转化为消息的调用 } function abc() public(){ testsetData(); this.testsetData(); } } contract Test2 is Test { function setData(uint a) internal { data = a } } contract D { function readData() public { Test test = new Test(); test.setData(1);//x test.exSetData(1);//y tet.testsetData();//y } } pragma solidity ^0.4.0; contract Test{ uint internal data; // 构造函数 constructor () public { data = a; } event EVENTA(uint a); // 视图函数 function testView() public constant returns (uint) { // constant是view别名 // data = 1 x 不能修改状态变量 // emit EVENTA(1); x 不能出发事件 return data; } // 纯函数 function f() public pure returns (uint) { // return 1 * 2 + data; x 不能读取 // this.balance; x // msg.value; x return 1 * 2 + 3; } // 回退函数,一个函数只有一个回退函数,多个的话会出错 // 调用函数, // 1.给这个合约发送以太币 // 2.我们在给我们调用的这样合约的函数,但是这个合约函数实际上并不存在,这个时候也会被动的调用这个回退函数 // 就是我们在调用一个合约,没有匹配到对应的函数的时候,它就会调用回退函数 // 需要注意的是,这样一个回退函数,我们可以在里面加一些实现,比如触发了一个事件等等,需要注意的是,里面的实现应该尽量简单 // 否则,在给这个合约转账的时候,发送者容易因为gas不足而交易失败 function () public payable { emit EVENTA(1); } } contract Caller { // 合约想接受以太币,必须有回退函数 并且 必须带有payable function callTest(Test test) public { test.send(1 ether); } } pragma solidity ^0.4.0; contract AddrTest { // 余额 function deposit() public payable { } // 地址 function getBalance() public constant returns (uint) { return this.balance; } // 转账 function transferEther(address towho) public { towho.transfer(10); } } pragma solidity ^0.4.0 contract Sharer { function sendHalf(address addr) public payable returns (uint balance) { require(msg.value % 2 == 0); uint balanceBeforeTranfer = this.balance addr.transfer(msg.value / 2 + 1) assert(this.balance == balanceBeforeTranfer - msg.value / 2) return this.balance; } }
|
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |